﻿#ifndef JZCO_CO_COROUTINE_H_
#define JZCO_CO_COROUTINE_H_

#include <QObject>
#include <QThread>
#include <functional>
#include <QSharedPointer>
#include "JZCoContext.h"

class JZCoScheduler;
class JZCoCoroutine
{
public:
    static JZCoCoroutine* current();

    JZCoCoroutine(const std::function<void()> &func);
    virtual ~JZCoCoroutine();

    void run()
    {
        m_func();
    }
    void yield();
    void resume();

    void quit();
    bool isFinish();
    void waitFinish();

protected:
    friend JZCoScheduler;

    static JZCoCoroutine* m_current;
    bool m_interrupt;
    bool m_finish;
    JZCoContext* m_ctx;
    std::function<void()> m_func;
};
typedef QSharedPointer<JZCoCoroutine> JZCoCoroutinePtr;

class JZCoThread : public QThread 
{
public:
    JZCoThread(std::function<void()> func);

    virtual void run();

protected:
    std::function<void()> m_func;
};

class JZCoScheduler : public QObject
{
    Q_OBJECT

public:
    static JZCoScheduler* instance();

    JZCoScheduler();
    ~JZCoScheduler();
    
    void init();

    void startTask(JZCoCoroutinePtr task);
    void endTask(JZCoCoroutine *task);
    JZCoMainContext* context();

protected:
    QList<JZCoCoroutinePtr> m_coList;
    JZCoMainContext* m_ctx;
};
#define g_scheduler JZCoScheduler::instance()
#define jzco_await

void jzco_init();
void jzco_yield();
void jzco_sleep(int ms);
void jzco_waitThread(std::function<void()> func);                //开启一个线程执行任务
void jzco_waitCoroutine(const QList<JZCoCoroutinePtr> &co_list); //等待协程执行完毕

//开启一个协程
JZCoCoroutinePtr jzco_spawn(const std::function<void()> &func);


#endif // !JZCO_NET_WORK_H
